package com.novartis.nims.imagedc.util;

import java.awt.Color;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

@SuppressWarnings("serial")
public class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener {
	
	protected CheckBoxHeader rendererComponent;
	protected int column;
	protected boolean mousePressed = false;
	
	public CheckBoxHeader(ItemListener itemListener, boolean checked) {  
		rendererComponent = this;
		rendererComponent.addItemListener(itemListener);
		rendererComponent.setHorizontalAlignment(SwingConstants.CENTER);
		rendererComponent.setOpaque(false);
		rendererComponent.setColumn(column);  
		rendererComponent.setText("Check All");  
		rendererComponent.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
		rendererComponent.setBorderPaintedFlat(true);
		rendererComponent.setBorderPainted(true);
		rendererComponent.setSelected(checked);
	}
	
	public Component getTableCellRendererComponent(
			JTable table, Object value,  
			boolean isSelected, boolean hasFocus, int row, int column) {  
		if (table != null) {  
			JTableHeader header = table.getTableHeader(); 
			if (header != null) {
				rendererComponent.setForeground(header.getForeground());
				rendererComponent.setBackground(header.getBackground());
				rendererComponent.setFont(header.getFont());
				header.addMouseListener(rendererComponent);
			}
		}
		return rendererComponent;  
	}

	protected void setColumn(int column) {  
		this.column = column;  
	}

	public int getColumn() {  
		return column;  
	}

	protected void handleClickEvent(MouseEvent e) {  
		if (mousePressed) {  
			mousePressed=false;  
			JTableHeader header = (JTableHeader)(e.getSource());  
			JTable tableView = header.getTable();  
			TableColumnModel columnModel = tableView.getColumnModel();  
			int viewColumn = columnModel.getColumnIndexAtX(e.getX());  
			int column = tableView.convertColumnIndexToModel(viewColumn);  

			if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {  
				doClick();  
			}  
		}  
	}

	public void mouseClicked(MouseEvent e) {  
		handleClickEvent(e);  
		((JTableHeader)e.getSource()).repaint();  
	}

	public void mousePressed(MouseEvent e) {  
		mousePressed = true;  
	}

	public void mouseReleased(MouseEvent e) { }

	public void mouseEntered(MouseEvent e) { }
	
	public void mouseExited(MouseEvent e) { }
    
    /*
     * The following methods are overridden as a performance measure to 
     * to prune code-paths are often called in the case of renders
     * but which we know are unnecessary.  Great care should be taken
     * when writing your own renderer to weigh the benefits and 
     * drawbacks of overriding methods like these.
     */

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public boolean isOpaque() { 
	Color back = getBackground();
	Component p = getParent(); 
	if (p != null) { 
	    p = p.getParent(); 
	}
        
	// p should now be the JTable. 
	boolean colorMatch = (back != null) && (p != null) && 
	    back.equals(p.getBackground()) && 
			p.isOpaque();
	return !colorMatch && super.isOpaque(); 
    }

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     *
     * @since 1.5
     */
    public void invalidate() {}

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public void validate() {}

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public void revalidate() {}

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public void repaint(long tm, int x, int y, int width, int height) {}

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public void repaint(Rectangle r) { }

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     *
     * @since 1.5
     */
    public void repaint() {
    }

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {	
	// Strings get interned...
	if (propertyName=="text"
                || propertyName == "labelFor"
                || propertyName == "displayedMnemonic"
                || ((propertyName == "font" || propertyName == "foreground")
                    && oldValue != newValue
                    && getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey) != null)) {

            super.firePropertyChange(propertyName, oldValue, newValue);
        }
    }

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a> 
     * for more information.
     */
    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }	
}